package edu.isquen.core.document.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import edu.isquen.core.base.dao.BaseDAO;
import edu.isquen.core.datasource.model.DataSource;
import edu.isquen.core.datasource.service.DataSourceService;
import edu.isquen.core.document.model.Document;
import edu.isquen.core.document.model.Item;
import edu.isquen.core.form.model.Form;
import edu.isquen.util.factory.ServiceFactory;

public class DocumentDAO extends BaseDAO<Document> implements IDocumentDAO{

	private Connection conn = null;
	
	public DocumentDAO(String voClazzName){
		super(voClazzName);
	}

	public DocumentDAO(Connection conn) {
		this.conn = conn;
	}

	public void create(Object obj) throws Exception {
		Document doc = (Document) obj;
		createDocument(doc);
	}

	public void createDocument(Document doc) throws Exception {
		Form form = doc.getForm();
		PreparedStatement preStatement = null;
		Connection conn = null;
		if (form != null) {
			DataSourceService dtService = (DataSourceService) ServiceFactory
					.createProcess(DataSourceService.class.getName());
			conn = ((DataSource) dtService.doView(form.getDataSourceId()))
					.getConnection();
		}
		StringBuffer sql = new StringBuffer();
		StringBuffer sqlName = new StringBuffer();
		StringBuffer sqlValue = new StringBuffer();
		sqlName
				.append("INSERT INTO isquen_test."
						+ getFullTableName(form.getName())
						+ " (ID,NAME,FORMID,FORMNAME,CREATEDATE,AUTHOR,LASTMODIFYUSER,LASTMODIFYDATE,EDITABLE,DESCRIPTION");
		sqlValue.append("VALUES (?,?,?,?,?,?,?,?,?,?");
		Collection<Item> items = doc.getItems();
		if (!items.isEmpty()) {
			for (Iterator<Item> iter = items.iterator(); iter.hasNext();) {
				Item item = iter.next();
				sqlName.append(",ITEM_" + item.getName());
				sqlValue.append(",?");
			}
		}
		sqlName.append(")");
		sqlValue.append(")");
		sql.append(sqlName.toString()).append(sqlValue.toString());
		preStatement = conn.prepareStatement(sql.toString());
		preStatement.setString(1, doc.getId());
		preStatement.setString(2, doc.getName());
		preStatement.setString(3, doc.getFormId());
		preStatement.setString(4, doc.getFormName());
		preStatement.setObject(5, doc.getCreateDate());
		preStatement.setString(6, (doc.getAuthor()==null ? "":doc.getAuthor().getId()));
		preStatement.setString(7, (doc.getLastModifyUser()==null ? "" : doc.getLastModifyUser().getId()));
		preStatement.setObject(8, doc.getLastModifyDate());
		preStatement.setBoolean(9, doc.getEditAble());
		preStatement.setString(10, doc.getDescription());
		
		int j = 10;
		Iterator<Item> iter = items.iterator();
		while (iter.hasNext()) {
			Item item = (Item) iter.next();
			j++;
			prepItemData(preStatement, doc, j, item);
		}
		preStatement.execute();
	}

	private void prepItemData(java.sql.PreparedStatement ps, Document doc,
			int indx, Item fd) throws Exception {
		try {
			String fieldType = fd.getType();
			if (fieldType.equals(Item.VALUE_TYPE_NUMBER)) { // Double
				Double value = fd.getNumberValue();
				if (value == null || value.isNaN()) {
					ps.setDouble(indx, 0);
				} else {
					ps.setDouble(indx, value.doubleValue());
				}
				return;
			}

			if (fieldType.equals(Item.VALUE_TYPE_VARCHAR)) { // String
				String value = fd.getVarcharValue();
				if (value == null)
					value = "";
				ps.setString(indx, value);
				return;
			}

			if (fieldType.equals(Item.VALUE_TYPE_DATE)) { // Date
				Date value = fd.getDateValue();
				if (value == null) {
					ps.setNull(indx, Types.DATE);
				} else {
					ps.setTimestamp(indx, new Timestamp(value.getTime()));
				}

				return;
			}

			if (fieldType.equals(Item.VALUE_TYPE_TEXT)) { // TEXT
				String text = fd.getTextValue();
				ps.setString(indx, text);
				return;
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			System.err.println("table " + doc.getFormName()
					+ " ERR FIELD NAME->" + fd.getName());
			throw new Exception("prepData Error!!!");
		}

	}

	public String getFullTableName(String forname) {
		if (forname == null || forname.equals("")) {
			return null;
		}
		return "K_" + forname.trim().toUpperCase();
	}

	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}
}
